<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
    <title></title>
</head>
<body>

<script>
  const data = {foo: true, bar: true}

  function cleanup(effectFn) {
    for (let i = 0; i < effectFn.deps.length; i++) {
      effectFn.deps[i].delete(effectFn)
    }

    effectFn.deps.length = 0
  }

  let activeEffect
  const effect = (fn) => {
    const effectFn = () => {
      cleanup(effectFn)
      activeEffect = effectFn
      fn()
    }
    effectFn.deps = []
    effectFn()
  }

  const bucket = new WeakMap()

  function track(target, key) {
    if (!activeEffect) return
    let depsMap = bucket.get(target)
    if (!depsMap) {
      bucket.set(target, (depsMap = new Map()))
    }

    let deps = depsMap.get(key)
    if (!deps) {
      depsMap.set(key, (deps = new Set()))
    }
    deps.add(activeEffect)
    activeEffect.deps.push(deps)
  }

  function trigger(target, key) {
    const depsMap = bucket.get(target)
    if (!depsMap) {
      return
    }
    const effects = depsMap.get(key)
    const effectsToRun = new Set(effects)   // 防止死循环
    effectsToRun && effectsToRun.forEach(fn => fn())
  }

  const obj = new Proxy(data, {
    get(target, key) {
      track(target, key)
      return target[key]
    },
    set(target, key, newValue) {
      target[key] = newValue
      trigger(target, key)
      return true
    }
  })

  let temp1, temp2
  effect(function effectFn1() {
    console.log('effectFn1 run')
    effect(function effectFn2() {
      console.log('effectFn2 run')
      temp2 = obj.bar
    })
    temp1 = obj.foo
  })

  obj.foo = false
  // 输出
  // effectFn1 run
  // effectFn2 run
  // effectFn2 run

  // 问题出在 activeEffect = effectFn，effectFn2把effectFn1覆盖掉了
</script>
</body>
</html>
